#include "ParamRepDialog.h"
#include "ui_ParamRepDialog.h"



ParamRepDialog::ParamRepDialog(QWidget *parent, const ImageWindow *from, ImageWindow::Mode mode) :
    QDialog(parent), _mode(mode),_maxtotal(200),_mintotal(-100),_valuemode(0),_valuemin(0),_valuemax(0),_valuecenter(0),_spintemp(NULL),_checktemp(NULL),_radiotemp(NULL),
    ui(new Ui::ParamRepDialog)
{
    ui->setupUi(this);

    init(from);


}

ParamRepDialog::~ParamRepDialog()
{
    delete ui;
}

void ParamRepDialog::init(const ImageWindow *from){
    initInfo(from);
    initRound(from);
    initAbs(false);
    initCut(false);
    initStretch(false);
    initConvert(from);
    if(_mode==ImageWindow::CONS){
        ui->groupBox_6->hide();//Conversion
        ui->groupBox_7->hide();//choice image to modify
        ui->groupBox_8->hide();//LogSacale
    }

    QObject::connect(ui->radioMem,SIGNAL(toggled(bool)),this,SLOT(reacRadioMem(bool)));
    QObject::connect(ui->possibilityConversion,SIGNAL(toggled(bool)),this,SLOT(reacPosConv(bool)));
    QObject::connect(ui->checkBox,SIGNAL(toggled(bool)),this,SLOT(reacLog(bool)));
}

void ParamRepDialog::initRound(const ImageWindow *from){
    if(from->isStandard()){
        ui->groupBoxRound->hide();
    }else{
        ui->comboBoxRoundNeg->setCurrentIndex(1);
        ui->comboBoxRoundPos->setCurrentIndex(0);
    }
}

void ParamRepDialog::initCut(bool activate){
    int min = std::numeric_limits<int>::min();
    int max = std::numeric_limits<int>::max();

    _spintemp = ui->spinBoxOrderCut;
    _spintemp->setValue(0);
    _spintemp->setRange(-1,4);
    QObject::connect(_spintemp, SIGNAL(valueChanged(int)),
                     this, SLOT(CheckOrder()));

    _spintemp = ui->spinBoxCutDown;
    _spintemp->setValue(0);
    _spintemp->setRange(min,max);
    QObject::connect(_spintemp, SIGNAL(valueChanged(int)),
            this, SLOT(CheckCut()));

    _spintemp = ui->spinBoxCutUp;
    _spintemp->setValue(255);
    QObject::connect(_spintemp, SIGNAL(valueChanged(int)),
            this, SLOT(CheckCut()));

    _checktemp = ui->checkBoxCut;
    _checktemp->setChecked(false);
    QObject::connect(_checktemp, SIGNAL(stateChanged(int)),
            this, SLOT(ToggleOp()));

    ui->spinBoxOrderCut->setReadOnly(true);

    updateCut(activate);
}

void ParamRepDialog::updateCut(bool activate){
    ui->spinBoxOrderCut->setReadOnly(!activate);
    ui->spinBoxCutDown->setReadOnly(!activate);
    ui->spinBoxCutUp->setReadOnly(!activate);
    ui->spinBoxOrderCut->setValue(0);

}

void ParamRepDialog::initAbs(bool activate){
    QWidget *temp = NULL;

    _spintemp = ui->spinBoxOrderAbs;
    _spintemp->setValue(0);
    _spintemp->setRange(-1,4);
    QObject::connect(_spintemp, SIGNAL(valueChanged(int)),
                     this, SLOT(CheckOrder()));

    _checktemp = ui->checkBoxAbs;
    _checktemp->setChecked(false);
    QObject::connect(_checktemp, SIGNAL(stateChanged(int)),
            this, SLOT(ToggleOp()));

    ui->spinBoxOrderAbs->setReadOnly(true);

    updateAbs(activate);
}

void ParamRepDialog::updateAbs(bool activate){
    ui->spinBoxOrderAbs->setReadOnly(!activate);
    ui->spinBoxOrderAbs->setValue(0);
}

void ParamRepDialog::initStretch(bool activate){
    QWidget *temp = NULL;
    int min = std::numeric_limits<int>::min();
    int max = std::numeric_limits<int>::max();

    _spintemp = ui->spinBoxOrderStretch;
    _spintemp->setValue(0);
    _spintemp->setRange(-1,4);
    QObject::connect(_spintemp, SIGNAL(valueChanged(int)),
                     this, SLOT(CheckOrder()));

    _spintemp = ui->spinBoxStretchCenter;
    _spintemp->setValue(128);
    _spintemp->setRange(min,max);

    _spintemp = ui->spinBoxStretchLow;
    _spintemp->setValue(0);
    _spintemp->setRange(min,max);

    _spintemp = ui->spinBoxStretchUp;
    _spintemp->setValue(255);
    _spintemp->setRange(min,max);

    QObject::connect(ui->spinBoxStretchCenter, SIGNAL(valueChanged(int)),
            this, SLOT(CheckStretch()));
    QObject::connect(ui->spinBoxStretchLow, SIGNAL(valueChanged(int)),
            this, SLOT(CheckStretch()));
    QObject::connect(ui->spinBoxStretchUp, SIGNAL(valueChanged(int)),
            this, SLOT(CheckStretch()));

    _radiotemp = ui->radioButtonLinear;
    _radiotemp->setChecked(false);
    QObject::connect(_radiotemp, SIGNAL(pressed()),
            this, SLOT(ManageButton()));

    _radiotemp = ui->radioButtonFree;
    _radiotemp->setChecked(false);
    QObject::connect(_radiotemp, SIGNAL(pressed()),
            this, SLOT(ManageButton()));

    _radiotemp = ui->radioButtonDefault;
    _radiotemp->setChecked(true);
    QObject::connect(_radiotemp, SIGNAL(pressed()),
            this, SLOT(ManageButton()));


    _checktemp = ui->checkBoxStretch;
    _checktemp->setChecked(false);
    QObject::connect(_checktemp, SIGNAL(stateChanged(int)),
            this, SLOT(ToggleOp()));


    ui->spinBoxOrderStretch->setReadOnly(true);
    ui->spinBoxStretchCenter->setReadOnly(true);
    ui->spinBoxStretchLow->setReadOnly(true);
    ui->spinBoxStretchUp->setReadOnly(true);
    ui->radioButtonDefault->setCheckable(false);
    ui->radioButtonFree->setCheckable(false);
    ui->radioButtonLinear->setCheckable(false);
}

void ParamRepDialog::updateStretch(bool activate){
    ui->spinBoxOrderStretch->setReadOnly(!activate);
    ui->spinBoxOrderStretch->setValue(0);
    ui->radioButtonDefault->setCheckable(activate);
    ui->radioButtonFree->setCheckable(activate);
    ui->radioButtonLinear->setCheckable(activate);

    ui->radioButtonDefault->setChecked(activate);
    ui->radioButtonFree->setChecked(false);
    ui->radioButtonLinear->setChecked(false);
}

void ParamRepDialog::updateOptionStretch(QRadioButton* button){
    ui->spinBoxStretchLow->setValue(0);
    ui->spinBoxStretchCenter->setValue(128);
    ui->spinBoxStretchUp->setValue(255);

    if(button == ui->radioButtonDefault){//We disable all the button
        ui->spinBoxStretchLow->setReadOnly(true);
        ui->spinBoxStretchCenter->setReadOnly(true);
        ui->spinBoxStretchUp->setReadOnly(true);
    }else{
        ui->spinBoxStretchLow->setReadOnly(false);
        ui->spinBoxStretchCenter->setReadOnly(false);
        ui->spinBoxStretchUp->setReadOnly(false);
    }
}


void ParamRepDialog::ToggleOp(){
    _checktemp = static_cast<QCheckBox*>(QObject::sender()) ;
    bool activate = _checktemp->isChecked();


        if(_checktemp == ui->checkBoxAbs){
            updateAbs(activate);

        }else
        if(_checktemp == ui->checkBoxCut){
            updateCut(activate);
        }else
        if(_checktemp == ui->checkBoxStretch){
            updateStretch(activate);
            updateOptionStretch(ui->radioButtonDefault);
        }

}


void ParamRepDialog::CheckOrder(){
    _spintemp = static_cast<QSpinBox*>(QObject::sender()) ;
    int val = _spintemp->value();
    QSpinBox* temp1, *temp2;

    if(val!=0){
        if(_spintemp == ui->spinBoxOrderAbs){
            temp1=ui->spinBoxOrderCut;
            temp2=ui->spinBoxOrderStretch;
        }else if(_spintemp == ui->spinBoxOrderCut){
            temp1=ui->spinBoxOrderAbs;
            temp2=ui->spinBoxOrderStretch;
        }else if(_spintemp == ui->spinBoxOrderStretch){
            temp1=ui->spinBoxOrderCut;
            temp2=ui->spinBoxOrderAbs;
        }

        if(temp1->value()==val){
            val++;
        }
        if(temp2->value()==val){
            val++;
        }
    }
    if(val>3) val=0;
    _spintemp->setValue(val);
}

void ParamRepDialog::CheckCut(){
    _spintemp = static_cast<QSpinBox*>(QObject::sender()) ;
    if(ui->spinBoxCutDown == _spintemp && _spintemp->value() >= ui->spinBoxCutUp->value())
        _spintemp->setValue(ui->spinBoxCutUp->value()-1);
    if(ui->spinBoxCutUp == _spintemp && _spintemp->value() <= ui->spinBoxCutDown->value())
        _spintemp->setValue(ui->spinBoxCutDown->value()+1);
}

void ParamRepDialog::CheckStretch(){//case free
    _spintemp = static_cast<QSpinBox*>(QObject::sender()) ;

    //Policy default
        //void, the spinbox are read only
    if(ui->radioButtonLinear->isChecked()){//Policy Linear

        if(ui->spinBoxStretchLow == _spintemp || ui->spinBoxStretchCenter == _spintemp){
            int size = (ui->spinBoxStretchCenter->value() - ui->spinBoxStretchLow->value());
            ui->spinBoxStretchUp->setValue(ui->spinBoxStretchCenter->value()+size);
        }
    }

    //We check the values are correct
    if( ui->spinBoxStretchLow == _spintemp && _spintemp->value() >= ui->spinBoxStretchCenter->value()){
        ui->spinBoxStretchLow->setValue(ui->spinBoxStretchCenter->value()-1);
    }
    else
    if(ui->spinBoxStretchUp == _spintemp && _spintemp->value() <= ui->spinBoxStretchCenter->value()){
        ui->spinBoxStretchCenter->setValue(ui->spinBoxStretchCenter->value()+1);
    }
    else
    if(ui->spinBoxStretchCenter == _spintemp){
        if(_spintemp->value() >= ui->spinBoxStretchUp->value()){
            _spintemp->setValue(ui->spinBoxStretchUp->value()-1);
        }else if(_spintemp->value() <= ui->spinBoxStretchLow->value()){
            _spintemp->setValue(ui->spinBoxStretchLow->value()+1);
        }
    }


}

void ParamRepDialog::ManageButton(){
    _radiotemp = static_cast<QRadioButton*>(QObject::sender()) ;
    if(ui->radioButtonDefault != _radiotemp) ui->radioButtonDefault->setChecked(false);
    if(ui->radioButtonLinear != _radiotemp) ui->radioButtonLinear->setChecked(false);
    if(ui->radioButtonFree != _radiotemp) ui->radioButtonFree->setChecked(false);
    _radiotemp->setChecked(true);
    updateOptionStretch(_radiotemp);


}


int ParamRepDialog::returnOrd(int ord){
    if(ui->spinBoxOrderAbs->value() == ord) return ParamRepDialog::ABS;
    if(ui->spinBoxOrderCut->value() == ord) return ParamRepDialog::CUT;
    if(ui->spinBoxOrderStretch->value() == ord) return ParamRepDialog::NORM;
}


void ParamRepDialog::initInfo(const ImageWindow *from){
    QStandardItemModel *model = new QStandardItemModel(4,3,this);
    model->setHorizontalHeaderItem(this->RED, new QStandardItem(QString("Red")));
    model->setHorizontalHeaderItem(this->GREEN, new QStandardItem(QString("Green")));
    model->setHorizontalHeaderItem(this->BLUE, new QStandardItem(QString("Blue")));
    model->setVerticalHeaderItem(this->MIN, new QStandardItem(QString("Min")));
    model->setVerticalHeaderItem(this->MEAN, new QStandardItem(QString("Mean")));
    model->setVerticalHeaderItem(this->MAX, new QStandardItem(QString("max")));
    model->setVerticalHeaderItem(this->STDDEV, new QStandardItem(QString("Std. Dev.")));



    if(from->isStandard()){
        const StandardImageWindow * siw = dynamic_cast<const StandardImageWindow*>(from);
        const Image_t<int> *image = siw->getImage();
        for(int k=0;k<image->getNbChannels();k++){
            model->setItem(this->MIN,k,new QStandardItem(QString("%1").arg(image->min(k))));
            model->setItem(this->MEAN,k,new QStandardItem(QString("%1").arg(image->mean(k))));
            model->setItem(this->MAX,k,new QStandardItem(QString("%1").arg(image->max(k))));
            model->setItem(this->STDDEV,k,new QStandardItem(QString("%1").arg(image->deviation((unsigned int)(k)))));
        }

    }else{
        const DoubleImageWindow * diw = dynamic_cast<const DoubleImageWindow*>(from);
        const Image_t<double> *image = diw->getImage();
        for(int k=0;k<image->getNbChannels();k++){
            model->setItem(this->MIN,k,new QStandardItem(QString("%1").arg(image->min(k))));
            model->setItem(this->MEAN,k,new QStandardItem(QString("%1").arg(image->mean(k))));
            model->setItem(this->MAX,k,new QStandardItem(QString("%1").arg(image->max(k))));
            model->setItem(this->STDDEV,k,new QStandardItem(QString("%1").arg(image->deviation((unsigned int)(k)))));
        }
    }
    ui->tableViewInfo->setModel(model);
    ui->tableViewInfo->resizeColumnsToContents();
}

void ParamRepDialog::initConvert(const ImageWindow *from){
    QString text;
    if(from->isStandard()){
        text= QString(tr("Conversion from Integer to Real"));
    }else{
        text= QString(tr("Conversion from Real to Integer"));
    }

    ui->possibilityConversion->setText(text);
}


void ParamRepDialog::reacRadioMem(bool val){
    if(val == false) ui->checkBox_2->setChecked(false);
    ui->checkBox_2->setCheckable(val);
}

void ParamRepDialog::reacPosConv(bool val){
    ui->radioButton->setChecked(val);
    ui->radioButton_2->setChecked(false);
    ui->radioButton->setCheckable(val);
    ui->radioButton_2->setCheckable(val);
}

void ParamRepDialog::reacLog(bool val){
    ui->doubleSpinBox->setReadOnly(!val);
    if(val == true) ui->doubleSpinBox->setValue(0);
}

ParamRep * ParamRepDialog::getParam(){
    /*
    int setting[SIZEPARAMREP];

    for(int ind = ParamRep::START;ind < ParamRep::END;ind++)
        setting[ind]=0;
        */
    //START, STANDARDCUT, STANDARDABS, STANDARDNORM, FLOATINF, FLOATSUP, LOGSCALE, LOGVAL,
    //VALMIN, VALMAX, VALCENTER, VALBEFCENTER, INHERITED, ORD1, ORD2, ORD3, CUTUP,CUTDOWN,
    //        IMMEMORY,NEWIM,CONVERT,CONBEFORE,DOUBLE, END
    for(int ind = ParamRep::START;ind < ParamRep::END;ind++){
        /**
        switch(ind){
            case ParamRep::START        :  ;break;
            case ParamRep::STANDARDCUT  :  setting[ind]= ui->checkBoxCut->isChecked();break;
            case ParamRep::STANDARDNORM :  setting[ind]= ui->checkBoxStretch->isChecked();break;
            case ParamRep::STANDARDABS  :  setting[ind]= ui->checkBoxAbs->isChecked();break;
            case ParamRep::FLOATINF     :  setting[ind]= ui->comboBoxRoundNeg->currentIndex();break;
            case ParamRep::FLOATSUP     :  setting[ind]= ui->comboBoxRoundPos->currentIndex();break;
            case ParamRep::LOGSCALE     :  setting[ind]= ui->checkBox->isChecked();break;
            case ParamRep::LOGVAL       :  setting[ind]= ui->doubleSpinBox->value();break;
            case ParamRep::VALMIN       :  setting[ind]= ui->spinBoxStretchLow->value();break;
            case ParamRep::VALMAX       :  setting[ind]= ui->spinBoxStretchUp->value();break;
            case ParamRep::VALCENTER    :  setting[ind]= ui->spinBoxStretchCenter->value();break;
            case ParamRep::VALBEFCENTER :  ;break;
            case ParamRep::INHERITED    :  setting[ind]= ui->checkBoxInheritance->isChecked();break;
            case ParamRep::ORD1         :  setting[ind]= returnOrd(1);break;
            case ParamRep::ORD2         :  setting[ind]= returnOrd(2);break;
            case ParamRep::ORD3         :  setting[ind]= returnOrd(3);break;
            case ParamRep::CUTUP        :  setting[ind]= ui->spinBoxCutUp->value();break;
            case ParamRep::CUTDOWN      :  setting[ind]= ui->spinBoxCutDown->value();break;
            case ParamRep::IMMEMORY     :  setting[ind]= ui->radioMem->isChecked();break;
            case ParamRep::NEWIM        :  setting[ind]= ui->checkBox_2->isChecked();break;
            case ParamRep::CONVERT      :  setting[ind]= ui->possibilityConversion->isChecked();break;
            case ParamRep::CONBEFORE    :  setting[ind]= ui->radioButton->isChecked();break;
            case ParamRep::DOUBLE       :  ;break;
            case ParamRep::END          :  ;break;
        }
        **/
    }
    /*
    setting[ParamRep::START]=231;
    setting[ParamRep::END]=45;
    ParamRep *param = new ParamRep(setting);
    */

    //return param;
    return NULL;
}












